package qj.tool.gae;

import java.util.Map;
import java.util.Map.Entry;

import org.mozilla.javascript.Context;
import org.mozilla.javascript.NativeJavaObject;
import org.mozilla.javascript.ScriptableObject;

import qj.util.Cols;

public class ScriptUtil {
	public static Object eval(String script, Object... ctx) {
		Context cx = Context.enter();
		try {
			ScriptableObject scope = cx.initStandardObjects();
			
			Map<String, Object> ctxMap = Cols.map_s(ctx);
			setScope(ctxMap, scope);

			Object eval;
			if (ctxMap != null && ctxMap.containsKey("me")) {
				eval = cx.evaluateString(scope, "with (me) {" + script + "}", null, 0, null);
			} else {
				eval = cx.evaluateString(scope, script, null, 0, null);
			}
			if (eval instanceof NativeJavaObject) {
				return ((NativeJavaObject)eval).unwrap();
			} else {
				return eval;
			}
		} finally {
			Context.exit();
		}
	}

	private static void setScope(Map<String, Object> ctxMap, ScriptableObject scope) {
		if (ctxMap==null) {
			return;
		}
		
		for (Entry<String, Object> entry : ctxMap.entrySet()) {
			Object wrapped = Context.javaToJS(entry.getValue(), scope);
			ScriptableObject.putProperty(scope, entry.getKey(), wrapped);
		}
	}
	
	public static void main(String[] args) {
		eval("print('1')", "me", System.out);
	}
}
